// 引入依赖包
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:buffer/buffer.dart';
import '../isolate/utils/ly_log.dart';

class LYSocketManager {
  Function(int dataLen, List<int> data)? callBack;
  LYSocketManager._internal();
  static final LYSocketManager _instance = LYSocketManager._internal();
  static LYSocketManager get share {
    return _instance;
  }

  Socket? _socket;
  List<int> receiveList = [];
  final int _headerLength = 4;

  Future<bool> initSocket(Function(int dataLen, List<int> data)? messageCallBack) async {
    callBack = messageCallBack;
    return await _connectSocket();
  }

  Future<bool> _connectSocket() async {
    const host = "192.168.110.119";
    const port = 1234;
    try {
      _socket = await Socket.connect(host, port, timeout: const Duration(seconds: 5));
      _socket?.listen(
        onReceivedMsg,
        onError: onError,
        onDone: onDone,
        cancelOnError: false,
      );
      return true;
    } catch (error) {
      if (error is SocketException) {
        LYLog.d('$error');
      }
      LYLog.d('===SocketException=======$error');
    }
    return false;
  }

  void onError(error) {
    LYLog.d('error===========$error');
    _connectSocket();
  }

  void onDone() {}

  //接收到socket消息
  onReceivedMsg(data) async {
    receiveList = receiveList + data;
    LYLog.d(receiveList);
    while (receiveList.length >= _headerLength) {
      int msgSize = byteToNum(receiveList.sublist(0, 4));
      LYLog.d("msgLength=$msgSize");
      if (receiveList.length >= (_headerLength + msgSize)) {
        LYLog.d("received=${receiveList.length}和msgLength=$msgSize验证通过->消息截取");
        //当收到的消息超过消息头描述的消息体长度时取出消息
        List<int> bodyList = receiveList.sublist(_headerLength, _headerLength + msgSize);
        //读取后删除已读取的消息
        receiveList.removeRange(0, _headerLength + msgSize);
        LYLog.d('receiveList->$receiveList');
        if (callBack != null) {
          callBack!(msgSize, bodyList);
        }
      } else {
        LYLog.d('received=${receiveList.length}小于msgLength=$msgSize->等待消息收取完成');
        break;
      }
    }
  }

  int byteToNum(List<int> list) {
    Uint8List resultList = Uint8List.fromList(list);
    ByteData byteData = ByteData.view(resultList.buffer);
    return byteData.getInt32(0);
  }

  void sendMessage({dynamic content}) async {
    try {
      ByteDataWriter contentWrite = ByteDataWriter(endian: Endian.big);
      final json = jsonEncode(content);
      contentWrite.writeInt32(json.length);
      contentWrite.write(json.codeUnits);
      final data = String.fromCharCodes(contentWrite.toBytes());
      _socket?.write(data);
      await _socket?.flush();
    } catch (error) {
      LYLog.d('=====$error');
    }
  }

// startHeartBeat() {
// _timer ??= Timer.periodic(const Duration(seconds: 1), (time) {
//   heartBeat++;
//   if (heartBeat > 40) {
//     heartBeat = 0;
//     //重连
//     if (socketAddress != null && socketPort != null) {
//       connectByAddress(socketAddress!, socketPort!);
//     }
//   }
// });
// }
}

// class LYSocketManager {
//   Function(int slamOrAPP, int msgID, int dataLen, dynamic data)? callBack;
//   LYSocketManager._internal();
//   static final LYSocketManager _instance = LYSocketManager._internal();
//   static LYSocketManager get share {
//     return _instance;
//   }
//
//   Socket? _socket;
//   List<int> receiveList = [];
//   bool isPackRead = false;
//   void initSocket(
//       Function(int slamOrAPP, int msgID, int dataLen, dynamic data)?
//           messageCallBack) {
//     callBack = messageCallBack;
//     // const host = "192.168.110.126";
//     const host = "192.168.110.101";
//     const port = 8080;
//     // const host = "124.222.224.186";
//     // const port = 8800;
//     Socket.connect(host, port, timeout: const Duration(seconds: 5))
//         .then((socket) async {
//       debugPrint('--------success----------');
//       _socket = socket;
//       _socket?.listen(
//         onReceivedMsg,
//         onError: onError,
//         onDone: onDone,
//         cancelOnError: false,
//       );
//     }).catchError((error) {
//       if (error is SocketException) {
//         debugPrint('$error');
//       }
//       debugPrint('===SocketException=======$error');
//     });
//   }
//
//   void onError(error) {
//     debugPrint('error===========${error}');
//   }
//
//   void onDone() {}
//
//   //接收到socket消息
//   onReceivedMsg(event) async {
//     String bodyStr = utf8.decode(event);
//     debugPrint('--------------$event===$bodyStr');
//     receiveList = receiveList + event;
//     //当接收到的数据长度大于8读取消息头
//     if (isPackRead) {
//       while (receiveList.length > 4) {
//         isPackRead = false;
//         int headerLength = 4;
//         //读取消息体长度
//         int msgLength = byteToNum(receiveList.sublist(0, 4));
//
//         //当收到的消息超过消息头描述的消息体长度时取出消息体并解码
//         if (receiveList.length >= headerLength + msgLength) {
//           List<int> bodyList =
//               receiveList.sublist(headerLength, headerLength + msgLength);
//           String bodyStr = utf8.decode(bodyList);
//           //这里处理已经读取的Socket消息内容 进行解base64或者解密
//           debugPrint(bodyStr);
//
//           //读取后删除已读取的消息
//           receiveList = receiveList.sublist(headerLength + msgLength);
//           if (receiveList.isEmpty) {
//             isPackRead = true;
//           }
//         } else {
//           isPackRead = true;
//           break;
//         }
//       }
//     }
//   }
//
//   //小端转大端
//   Uint8List int32BigEndianBytes(int value) {
//     return Uint8List(4)..buffer.asByteData().setUint32(0, value, Endian.big);
//   }
//
//   //大端转小端
//   int byteToNum(List<int> list) {
//     Uint8List resultList = Uint8List.fromList(list);
//     ByteData byteData = ByteData.view(resultList.buffer);
//     return byteData.getInt32(0);
//   }
//
//   void sendMessage(int slamOrAPP, int msgID, dynamic content) async {
//     // final msg = LYWebSocketManager.writeDataWithModel(
//     //     LYMessageModel(slamOrAPP: slamOrAPP, msgID: msgID, data: content));
//     // final msg = "123";
//     // Codec<String, String> stringToBase64 = utf8.fuse(base64);
//     // String base64Str = stringToBase64.encode(msg);
//     try {
//       final json = jsonEncode(content);
//       ByteDataWriter contentWrite = ByteDataWriter(endian: Endian.big);
//       contentWrite.writeInt32(slamOrAPP);
//       contentWrite.writeInt32(msgID);
//       contentWrite.writeInt32(json.length);
//       contentWrite.write(json.codeUnits);
//       final data = String.fromCharCodes(contentWrite.toBytes());
//       debugPrint('-------------$data');
//       _socket?.write(data);
//       await _socket?.flush();
//     } catch (error) {
//       debugPrint('=====$error');
//     }
//   }
//
//   startHeartBeat() {
//     // _timer ??= Timer.periodic(const Duration(seconds: 1), (time) {
//     //   heartBeat++;
//     //   if (heartBeat > 40) {
//     //     heartBeat = 0;
//     //     //重连
//     //     if (socketAddress != null && socketPort != null) {
//     //       connectByAddress(socketAddress!, socketPort!);
//     //     }
//     //   }
//     // });
//   }
//
//   // 模型数据 --> 二进制数据
//   static Uint8List writeDataWithModel(LYMessageModel model) {
//     ByteDataWriter contentWrite = ByteDataWriter(endian: Endian.big);
//     contentWrite.writeInt32(model.slamOrAPP?.toInt() ?? 0);
//     contentWrite.writeInt32(model.msgID?.toInt() ?? 0);
//     // List<int> allKeys = model.data.keys.toList();
//     // for (int i = 0; i < allKeys.length; i++) {
//     //   int key = allKeys[i];
//     //   String value = model.body[key];
//     //   contentWrite.writeInt32(key);
//     //   contentWrite.writeInt32(value.length);
//     //   contentWrite.write(value.toString().codeUnits);
//     // }
//     // final json = jsonEncode(model.data);
//     // contentWrite.writeInt32(json.length);
//     // contentWrite.write(json.codeUnits);
//     return contentWrite.toBytes();
//   }
// }
